package com.cqie.service.impl;

import com.cqie.dto.user.PatientLoginDto;
import com.cqie.entity.PatientLogin;
import com.cqie.exception.SpecialException;
import com.cqie.mapper.user.PatientLoginMapper;
import com.cqie.service.IPatientLoginService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqie.util.JwtTokenUtil;
import com.cqie.util.Md5Util;
import com.cqie.util.RedisUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 不吃海鲜
 * @since 2024-11-26
 */
@Service
@Slf4j
public class PatientLoginServiceImpl extends ServiceImpl<PatientLoginMapper, PatientLogin> implements IPatientLoginService {


    @Resource
    private PatientLoginMapper patientLoginMapper;

    private final RedisUtils redisUtils;

    public PatientLoginServiceImpl(RedisUtils redisUtils) {
        this.redisUtils = redisUtils;
    }

    /**
     * 患者注册
     * @param patientLoginDto
     * @return
     */
    @Override
    public Boolean registerPatient(PatientLoginDto patientLoginDto) throws SpecialException {
        // 查询数据库全部数据
        var patientLoginList = patientLoginMapper.getPatientLoginList();

        // 判断数据库中是否已存在该账号和电话号码
        var data = patientLoginList.stream()
                .anyMatch(s -> s.getPatientAccount().equals(patientLoginDto.getPatientAccount())
                        || s.getPatientPhone().equals(patientLoginDto.getPatientPhone()));

        // 如果存在则抛出异常
        if (data && patientLoginList.size() > 0) {
            throw new SpecialException("该账号或者电话已存在");
        }

        // 将密码加密然后放到实体类中
        try {
            PatientLogin patientLogin = PatientLogin.builder()
                    .patientAccount(patientLoginDto.getPatientAccount())
                    .patientPassword(Md5Util.md5(patientLoginDto.getPatientPassword()))
                    .patientPhone(patientLoginDto.getPatientPhone())
                    .build();

            // 将实体类存入数据库
            patientLoginMapper.insert(patientLogin);
            return true;
        } catch (Exception e) {
            throw new SpecialException("密码加密失败");
        }
    }

    /**
     * 患者登陆
     * @param patientLoginDto
     * @return
     */
    @Override
    public String loginPatient(PatientLoginDto patientLoginDto) {
        try {
            var patientLoginEntity = patientLoginMapper.selectByAccount(patientLoginDto.getPatientAccount());
            var checkPassWord = Md5Util.passwordVerify(patientLoginDto.getPatientPassword(), patientLoginEntity.getPatientPassword());

            if (checkPassWord && !ObjectUtils.isEmpty(patientLoginEntity) ) {
                // 生成一个安全的令牌，用于在客户端和服务器之间进行身份验证和授权
                var token = JwtTokenUtil.buildJwt(patientLoginEntity.getPatientId(),
                        patientLoginEntity.getPatientAccount());

                if (!StringUtils.hasText(token)){
                    throw new SpecialException("token生成失败");
                }
                token = "patient:" + token;
                log.info("用户登录成功，生成token为：" + token);

                // k : token v: DoctorsLoginEntity 过期时间: 15min 单位: 毫秒
                var saveTokenToRedis = redisUtils.set(token , patientLoginEntity , JwtTokenUtil.KEEP_TIME ,
                        TimeUnit.MILLISECONDS);
                log.info("token存入redis结果: " + saveTokenToRedis);
                if (!saveTokenToRedis){
                    throw new SpecialException("token存入redis失败");
                }

                return token;

            }else {
                log.info("密码校验结果: " + checkPassWord);
                throw new SpecialException("密码校验结果错误");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }


}
